﻿//TODO: test (and implement?) LinearInterpolation

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// 
    /// </summary>
    public class LinearInterpolation : BaseImageFilter
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="LinearInterpolation"/> class.
        /// </summary>
        public LinearInterpolation()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="LinearInterpolation"/> class.
        /// </summary>
        /// <param name="_linearInterpolation">The _linear interpolation.</param>
        internal LinearInterpolation(LinearInterpolation _linearInterpolation)
        {
        }

        /// <summary>
        /// Execute this Filter
        /// A Debug Statement is written if a concrete Filter is called
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            base.Execute(_bitmap);
            return _bitmap;
        }

        /// <summary>
        /// Linears the interpolate.
        /// </summary>
        /// <param name="A">The A.</param>
        /// <param name="B">The B.</param>
        /// <param name="l">The l.</param>
        /// <param name="L">The L.</param>
        /// <returns></returns>
        protected long LinearInterpolate(int A, int B, int l, int L)
        {
            // extract r, g, b information
            // A and B is a ARGB-packed int so we use bit operation to extract
            int Ar = (A >> 16) & 0xff;
            int Ag = (A >> 8) & 0xff;
            int Ab = A & 0xff;
            int Br = (B >> 16) & 0xff;
            int Bg = (B >> 8) & 0xff;
            int Bb = B & 0xff;
            // now calculate Y. convert float to avoid early rounding
            // There are better ways but this is for clarity's sake
            int Yr = (int)(Ar + l * (Br - Ar) / (float)L);
            int Yg = (int)(Ag + l * (Bg - Ag) / (float)L);
            int Yb = (int)(Ab + l * (Bb - Ab) / (float)L);
            // pack ARGB with hardcoded alpha
            return 0xff000000 // alpha
            | ((Yr << 16) & 0xff0000)
            | ((Yg << 8) & 0xff00)
            | (Yb & 0xff);
        }

        /// <summary>
        /// This is used to clone a filter, each filter must implement it's own clone functionality
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new LinearInterpolation(this);
        }
    }
}
